package se.teamscape.client.presenter;

import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.widget.WidgetDisplay;
import net.customware.gwt.presenter.client.widget.WidgetPresenter;

/**
 * 
 * A base presenter inheriting from WidgetPresenter. That way we only override a
 * method when we actually need it, instead of having lots of unimplemented
 * methods in each presenter.
 * 
 * We have support for lazy loading and keeping track of if data is up to date
 * here.
 * 
 * 
 * @author Andreas Borglin
 */
public abstract class BasePresenter<D extends BasePresenter.Display> extends WidgetPresenter<D> {

    // All presenters use some model id to fetch data.
    // We save this here and keep track of changes so we know
    // when we need to update data in the presenter
    private String mId;
    private boolean mNeedsUpdate = true;
    private boolean mFirstReveal = true;

    public interface Display extends WidgetDisplay {

        // For lazy loading of views
        void init();

    }

    public BasePresenter(D display, EventBus eventBus) {
        super(display, eventBus);
    }

    public void setId(String id) {

        if (id == null) {
            mId = null;
        }

        else if (mId == null || !mId.equals(id)) {
            mId = id;
            mNeedsUpdate = true;
        }
    }

    /*
     * Do we need to update the view data?
     */
    protected boolean needsUpdate() {
        return mNeedsUpdate;
    }

    protected void viewUpdated() {
        mNeedsUpdate = false;
    }

    public String getId() {
        return mId;
    }

    /*
     * Override revealDisplay() to add support for lazy loading.
     * On first reveal, we initialize the view and call onLazyBind()
     * on the presenter.
     * (non-Javadoc)
     * 
     * @see net.customware.gwt.presenter.client.BasicPresenter#revealDisplay()
     */
    @Override
    public void revealDisplay() {

        if (mFirstReveal) {
            display.init();
            onLazyBind();
            mFirstReveal = false;
        }

        super.revealDisplay();
    }

    /*
     * Used like onBind(), but not called until
     * the first reveal on the presenter
     */
    protected abstract void onLazyBind();

    @Override
    protected void onBind() {

    }

    @Override
    protected void onUnbind() {

    }

}
